/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 98152
 * Date: 2025-10-20
 * Time: 10:36
 */
/*public class Main {
    public static int n = 6012707;
    public static void main(String[] args) {
        int e = 3674911;
        int d = 422191;
        int m = 5234673;
        int s = RSASign(d, m);
        int v = RSAVer(e, s);
        if(s == v) {
            System.out.println(true);
        } else {
            System.out.println(false);
        }
    }

    public static int RSASign(int privateKey, int input) {
        int output = (int)(Math.pow(input, privateKey) % n);
        System.out.println("签名为：" + output);
        return output;
    }

    public static int RSAVer(int publicKey, int input) {
        int output = (int)(Math.pow(input, publicKey) % n);
        System.out.println("由数字签名生成的数据为：" + output);
        return output;
    }
}*/


import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class Main {
    // 算法名称
    private static final String ALGORITHM = "RSA";
    // 签名算法
    private static final String SIGNATURE_ALGORITHM = "SHA256withRSA";
    // 密钥长度
    private static final int KEY_SIZE = 2048;

    public static void main(String[] args) throws Exception {
        // 原始数据
        String originalData = "这是一段需要签名的数据";
        System.out.println("原始数据: " + originalData);

        // 生成RSA密钥对
        KeyPair keyPair = generateKeyPair();
        PrivateKey privateKey = keyPair.getPrivate();
        PublicKey publicKey = keyPair.getPublic();

        // 对数据进行签名
        String signature = sign(originalData, privateKey);
        System.out.println("数字签名: " + signature);

        // 验证签名
        boolean verified = verify(originalData, signature, publicKey);
        System.out.println("签名验证结果: " + (verified ? "成功" : "失败"));

        // 测试篡改数据后的验证结果
        String tamperedData = "这是一段被篡改的数据";
        boolean tamperedVerified = verify(tamperedData, signature, publicKey);
        System.out.println("篡改数据后验证结果: " + (tamperedVerified ? "成功" : "失败"));
    }

    /**
     * 生成RSA密钥对
     */
    public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
        keyPairGenerator.initialize(KEY_SIZE);
        return keyPairGenerator.generateKeyPair();
    }

    /**
     * 对数据进行签名
     * @param data 要签名的数据
     * @param privateKey 私钥
     * @return 签名结果（Base64编码）
     */
    public static String sign(String data, PrivateKey privateKey) throws Exception {
        // 获取签名实例
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        // 初始化签名（使用私钥）
        signature.initSign(privateKey);
        // 更新要签名的数据
        signature.update(data.getBytes());
        // 执行签名
        byte[] signBytes = signature.sign();
        // 将签名结果进行Base64编码，方便传输
        return Base64.getEncoder().encodeToString(signBytes);
    }

    /**
     * 验证签名
     * @param data 原始数据
     * @param signatureStr 签名（Base64编码）
     * @param publicKey 公钥
     * @return 验证结果
     */
    public static boolean verify(String data, String signatureStr, PublicKey publicKey) throws Exception {
        // 获取签名实例
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        // 初始化验签（使用公钥）
        signature.initVerify(publicKey);
        // 更新要验证的数据
        signature.update(data.getBytes());
        // 将Base64编码的签名解码
        byte[] signBytes = Base64.getDecoder().decode(signatureStr);
        // 执行验签
        return signature.verify(signBytes);
    }

    /**
     * 将公钥转为Base64字符串（用于保存或传输）
     */
    public static String publicKeyToBase64(PublicKey publicKey) {
        return Base64.getEncoder().encodeToString(publicKey.getEncoded());
    }

    /**
     * 将Base64字符串转为公钥
     */
    public static PublicKey base64ToPublicKey(String publicKeyStr) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(publicKeyStr);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return keyFactory.generatePublic(keySpec);
    }

    /**
     * 将私钥转为Base64字符串（用于保存或传输）
     */
    public static String privateKeyToBase64(PrivateKey privateKey) {
        return Base64.getEncoder().encodeToString(privateKey.getEncoded());
    }

    /**
     * 将Base64字符串转为私钥
     */
    public static PrivateKey base64ToPrivateKey(String privateKeyStr) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(privateKeyStr);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return keyFactory.generatePrivate(keySpec);
    }
}